package de.hska.kundenverwaltung;

import java.io.File;
import java.util.Collection;
import java.util.List;

import de.hska.kundenverwaltung.db.BildException;
import de.hska.kundenverwaltung.db.Kunde;
import de.hska.kundenverwaltung.db.KundeDeletedException;
import de.hska.kundenverwaltung.db.KundeNotFoundException;
import de.hska.kundenverwaltung.db.KundeUpdatedException;

public interface Kundenverwaltung {
	
	/**
	 * @return Hoechste Kategorie
	 */
	short getMaxKategorie();
	
	/**
	 * @return Maximaler Rabattsatz
	 */
	float getMaxRabatt();

	/**
	 * @return Alle persistenten Kunden
	 */
	Collection<Kunde> findAllKunden();
	
	/**
	 * @return Alle Nachnamen von Kunden
	 */
	List<String> findAllNachnamen();
	
	/**
	 * @return Alle persistenten Kunden sortiert nach Id
	 */
	Collection<Kunde> findAllKundenId();

	/**
	 * Suche nach Kunden mit gleichem Nachnamen.
	 * @param nachname Suchkriterium
	 * @return Liste mit gefundenen Datens&auml;tzen
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidNachnameException Falls der Nachname syntaktisch falsch ist
	 */
	List<Kunde> findKunden(String nachname) throws KundeNotFoundException, KundeInvalidNachnameException;
	
	/**
	 * Suche nach Kunden mit gleichem Prefix f&uuml;r den Nachnamen.
	 * @param nachnamePrefix Suchkriterium
	 * @return Liste mit gefundenen Datens&auml;tzen
	 */
	List<Kunde> findKundenByNachnamePrefix(String nachnamePrefix);

	/**
	 * Suche nach Kunden mit gleichem Nachnamen einschlie&szlig;lich der Bestellungen und ggf. Lieferungen.
	 * @param nachname Suchkriterium
	 * @param mitLieferungen Sollen auch Lieferungen mitgeladen werden?
	 * @param toDir Zielverzeichnis f&uuml;r eventuelle (Bild-) Dateien
	 * @return Liste mit gefundenen Datens&auml;tzen
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidNachnameException Falls der Nachname syntaktisch falsch ist
	 */
	List<Kunde> findKundenMitBestellungenUndLieferungen(String nachname, boolean mitLieferungen)
		throws KundeNotFoundException, KundeInvalidNachnameException;

	/**
	 * @param id
	 * @return Der Kunde mit der gegebenen ID
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidIdException Falls die ID ung&uuml;ltig ist
	 */
	Kunde findKundeById(Long id) throws KundeNotFoundException, KundeInvalidIdException;

	/**
	 * @param id
	 * @return Der Kunde mit der gegebenen ID
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidIdException Falls die ID ung&uuml;ltig ist
	 */
	Kunde findKundeMitBestellungenById(Long id) throws KundeNotFoundException, KundeInvalidIdException;

	/**
	 * @param loginName
	 * @return Der Kunde mit dem gegebenen Usernamen
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 */
	Kunde findKundeByUserName(String userName) throws KundeNotFoundException;

	/**
	 * Eine Menge von Kunden soll gel&ouml;scht werden.
	 * NUR wegen Prog3: mengenwertige Schnittstelle, weil es komplizierter ist als nur einen Kunden zu l&ouml;schen.
	 * @param kunden Zu l&ouml;schende Datens&auml;tze
	 * @throws KundeDeleteBestellungException falls der zu l&ouml;schende Kunde mindestens 1 Bestellung hat
	 */
	void deleteKunden(Collection<Kunde> kunden) throws KundeDeleteBestellungException;
	
	/**
	 * Ein Kunde zu gegebener ID soll gel&ouml;scht werden, falls er keine Bestellungen hat.
	 * @param kundeId Die ID des zu l&ouml;schenden Kunden
	 * @throws KundeDeleteBestellungException falls der zu l&ouml;schende Kunde mindestens 1 Bestellung hat
	 * @throws KundeInvalidIdException Falls die ID ung&uuml;ltig ist
	 */
	void deleteKundeById(Long kundeId) throws KundeDeleteBestellungException, KundeInvalidIdException;

	/**
	 * Neue Kunden sollen angelegt werden.
	 * NUR wegen Prog3: mengenwertige Schnittstelle, weil es komplizierter ist als nur einen Kunden zu erzeugen.
	 * @param kunden Neue Kundendaten
	 * @return Die neuen Kundendaten inkl. der aktualisierten IDs
	 * @throws KundeDuplikatException falls ein Duplikat erzeugt werden soll
	 * @throws KundeCreateAdresseException falls der Kunde keine Adresse hat
	 */
	Collection<Kunde> createKunden(Collection<Kunde> kunden) throws KundeCreateAdresseException, KundeDuplikatException;

	/**
	 * Existierende Kundendaten sollen ge&auml;ndert werden.
	 * NUR wegen Prog3: mengenwertige Schnittstelle, weil es komplizierter ist als nur einen Kunden zu &auml;ndern.
	 * @param kunden Zu &auml;ndernde Kundendaten. Die Kunden-ID muss gesetzt sein.
	 * @return Die ge&auml;nderten Kunden
	 * @throws KundeDuplikatException falls ein Duplikat erzeugt werden soll
	 * @throws KundeDeletedException falls der Kunde bereits gel&ouoml;scht ist
	 * @throws KundeUpdatedException falls der Kunde bereits aktualisiert wurde
	 */
	Collection<Kunde> updateKunden(Collection<Kunde> kunden) throws KundeDuplikatException, KundeDeletedException, KundeUpdatedException;
	
	/**
	 * Zu einem Kunden ein Bild abspeichern
	 * @param kundeId Die ID des betroffenen Kunden
	 * @param bildBytes Das neue Bild als Byte-Array
	 * @param extension Extension der hochgeladenen Datei
	 * @return Das persistente Kunden-Objekt
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidIdException Falls die ID ung&uuml;ltig ist
	 * @throws BildException Falls beim Abspeichern des Bildes ein interner Fehler auftritt
	 */
	Kunde neuesBild(Long kundeId, byte[] bildBytes, String extension) throws KundeNotFoundException, KundeInvalidIdException, BildException;
	
	/**
	 * Zu einem Kunden ein Bild abspeichern
	 * @param kundeId Die ID des betroffenen Kunden
	 * @param bildTmpFile Das neue Bild als tempor&auml;res File-Objekt
	 * @param extension Extension der hochgeladenen Datei
	 * @return Das persistente Kunden-Objekt
	 * @throws KundeNotFoundException Falls kein Kunde gefunden wurde
	 * @throws KundeInvalidIdException Falls die ID ung&uuml;ltig ist
	 * @throws BildException Falls beim Abspeichern des Bildes ein interner Fehler auftritt
	 */
	Kunde neuesBild(Long kundeId, File bildTmpFile, String extension) throws KundeNotFoundException, KundeInvalidIdException, BildException;
}